<template>
  <el-config-provider :locale="zhCn">
  <div class="page">
    <div class="toolbar">
      <el-form :inline="true" :model="filters" class="filters">
        <el-form-item label="活动名称">
          <el-input v-model="filters.name" placeholder="请输入" clearable />
        </el-form-item>
        <el-form-item label="活动类型">
          <el-select v-model="filters.activity_type_id" placeholder="请选择" clearable style="min-width:200px">
            <el-option v-for="t in activityTypes" :key="t.code" :label="t.name" :value="t.code" />
          </el-select>
        </el-form-item>
        <el-form-item label="行政区划">
          <el-cascader v-model="filters.regionCodes" :options="regionOptions" :props="{ checkStrictly: true, emitPath: true }" placeholder="请选择省/市/区" clearable @change="onRegionFilterChange" />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="filters.status" placeholder="全部" clearable style="min-width:140px">
            <el-option label="草稿" value="draft" />
            <el-option label="待执行" value="ready" />
            <el-option label="执行中" value="in_progress" />
            <el-option label="待总结" value="to_summarize" />
            <el-option label="评估中" value="evaluating" />
            <el-option label="已评估" value="evaluated" />
            <el-option label="已归档" value="archived" />
          </el-select>
        </el-form-item>
        <el-form-item label="时间范围">
          <el-date-picker v-model="filters.timeRange" type="daterange" start-placeholder="开始" end-placeholder="结束" value-format="YYYY-MM-DD" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="reload">查询</el-button>
          <el-button @click="resetFilters">重置</el-button>
        </el-form-item>
      </el-form>
      <div class="actions">
        <el-button type="primary" @click="openCreate">新建活动</el-button>
      </div>
    </div>
    <div class="table-area">
      <div class="table-container">
        <el-table :data="items" style="width:100%" max-height="100%">
          <el-table-column prop="name" label="名称" min-width="160" />
          <el-table-column label="类型" min-width="160">
            <template #default="{ row }">{{ idToName[row.activity_type_id] || row.activity_type_id }}</template>
          </el-table-column>
          <el-table-column prop="time_start" label="开始时间" min-width="180" />
          <el-table-column prop="time_end" label="结束时间" min-width="180" />
          <el-table-column prop="location_admin" label="行政区划" min-width="140" />
          <el-table-column prop="location_detail" label="详细地点" min-width="180" />
          <el-table-column prop="organizer" label="主办单位" min-width="140" />
          <el-table-column prop="status" label="状态" width="120" />
          <el-table-column prop="description" label="描述" min-width="240" show-overflow-tooltip />
          <el-table-column fixed="right" label="操作" width="300">
            <template #default="{ row }">
              <el-button @click="openEdit(row)">修改</el-button>
              <el-popconfirm title="确定删除该活动？" @confirm="remove(row)">
                <template #reference>
                  <el-button type="danger">删除</el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="pagination">
        <el-config-provider :locale="zhCn">
          <el-pagination
            background
            layout="prev, pager, next, sizes, jumper, total"
            :total="total"
            :page-size="pageSize"
            :current-page="page"
            :page-sizes="[10,20,50,100]"
            @size-change="onSizeChange"
            @current-change="onPageChange"
          />
        </el-config-provider>
      </div>
    </div>

    <el-dialog v-model="showDialog" :title="dialogTitle" width="640px" destroy-on-close>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
        <el-form-item label="名称" prop="name"><el-input v-model="form.name" /></el-form-item>
        <el-form-item label="类型" prop="activity_type_id">
          <el-select v-model="form.activity_type_id" placeholder="请选择活动类型" style="min-width:240px">
            <el-option v-for="t in activityTypes" :key="t.code" :label="t.name" :value="t.code" />
          </el-select>
        </el-form-item>
        <el-form-item label="开始日期" prop="time_start"><el-date-picker v-model="form.time_start" type="date" value-format="YYYY-MM-DD" /></el-form-item>
        <el-form-item label="结束日期" prop="time_end"><el-date-picker v-model="form.time_end" type="date" value-format="YYYY-MM-DD" /></el-form-item>
        <el-form-item label="行政区划" prop="location_admin">
          <el-cascader v-model="formRegionCodes" :options="regionOptions" :props="{ checkStrictly: true, emitPath: true }" placeholder="请选择省/市/区" clearable @change="onRegionFormChange" />
        </el-form-item>
        <el-form-item label="详细地点" prop="location_detail"><el-input v-model="form.location_detail" /></el-form-item>
        <el-form-item label="地图选点">
          <el-button @click="openMapPicker">打开地图</el-button>
          <span style="margin-left:12px">经纬度：{{ form.latitude ?? '-' }}, {{ form.longitude ?? '-' }}</span>
        </el-form-item>
        <el-form-item label="主办单位" prop="organizer"><el-input v-model="form.organizer" /></el-form-item>
        <el-form-item label="状态" prop="status"><el-select v-model="form.status" style="min-width:140px">
          <el-option label="草稿" value="draft" />
          <el-option label="待执行" value="ready" />
          <el-option label="执行中" value="in_progress" />
          <el-option label="待总结" value="to_summarize" />
          <el-option label="评估中" value="evaluating" />
          <el-option label="已评估" value="evaluated" />
          <el-option label="已归档" value="archived" />
        </el-select></el-form-item>
        <el-form-item label="联系人"><el-input v-model="form.contact_name" /></el-form-item>
        <el-form-item label="联系电话"><el-input v-model="form.contact_phone" /></el-form-item>
        <el-form-item label="描述" prop="description"><el-input v-model="form.description" type="textarea" rows="3" /></el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showDialog=false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="submit">保存</el-button>
      </template>
    </el-dialog>
    <el-dialog v-model="showMap" title="选择地点" width="820px" destroy-on-close @opened="onMapOpened" @closed="onMapClosed">
      <div class="map-tools">
        <el-input v-model="mapSearchText" placeholder="输入地址查找（如：湖北省武汉市江汉路）" style="max-width: 520px" />
        <el-button type="primary" :loading="geoLoading" @click="onMapSearch">搜索</el-button>
      </div>
      <div ref="mapEl" class="map-picker"></div>
      <template #footer>
        <el-button @click="showMap=false">取消</el-button>
        <el-button type="primary" @click="confirmMapPick">确定</el-button>
      </template>
    </el-dialog>
  </div>
  </el-config-provider>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import { api } from '../../api/client'
import { regionData } from 'element-china-area-data'
import { nextTick } from 'vue'
import 'leaflet/dist/leaflet.css'
import L from 'leaflet'

type Activity = {
  id: string
  name: string
  activity_type_id: string
  time_start?: string | null
  time_end?: string | null
  location_admin: string
  location_detail: string
  latitude?: number | null
  longitude?: number | null
  description: string
  organizer: string
  contact_name?: string | null
  contact_phone?: string | null
  approver_name?: string | null
  approved_at?: string | null
  approval_result?: string | null
  status: string
}

type DictItem = { id: string; code: string; name: string }

const items = ref<Activity[]>([])
const page = ref(1)
const pageSize = ref(10)
const total = ref(0)

const activityTypes = ref<DictItem[]>([])
const codeToId = ref<Record<string, string>>({})
const idToCode = ref<Record<string, string>>({})
const idToName = ref<Record<string, string>>({})
const regionOptions = regionData as any

const router = useRouter()

function goToEvents(row: Activity) {
  router.push({ path: '/admin/events', query: { activity_id: row.id } })
}
function goToArchives(row: Activity) {
  router.push({ path: `/admin/archives/${row.id}` })
}
const filters = reactive({
  name: '',
  activity_type_id: '',
  location_admin: '',
  regionCodes: [] as string[],
  status: '',
  timeRange: [] as string[]
})

function resetFilters() {
  filters.name = ''
  filters.activity_type_id = ''
  filters.location_admin = ''
  filters.status = ''
  filters.timeRange = []
}

async function load() {
  const params: any = { page: page.value, page_size: pageSize.value }
  if (filters.name) params.name = filters.name
  if (filters.activity_type_id) params.activity_type_id = codeToId.value[filters.activity_type_id] || filters.activity_type_id
  if (filters.location_admin) params.location_admin = filters.location_admin
  if (filters.status) params.status = filters.status
  if (filters.timeRange && filters.timeRange.length === 2) {
    params.time_start = filters.timeRange[0]
    params.time_end = filters.timeRange[1]
  }
  const res = await api.get('/activities', { params })
  const data = res.data
  items.value = Array.isArray(data.items) ? data.items : Array.isArray(data) ? data : []
  total.value = typeof data.total === 'number' ? data.total : typeof data.total_count === 'number' ? data.total_count : Number(res.headers['x-total-count'] ?? items.value.length)
}

function labelsFromCodes(codes: string[]): string {
  const labels: string[] = []
  let nodes: any[] = regionOptions as any[]
  (codes || []).forEach((code) => {
    const n = nodes?.find((x: any) => x.value === code || x.code === code)
    if (n) {
      labels.push(n.label || n.name)
      nodes = n.children || []
    }
  })
  return labels.join(' / ')
}

function codesFromLabels(labelPath: string): string[] {
  const names = (labelPath || '')
    .split(/\s*\/\s*/)
    .filter(Boolean)
  let nodes: any[] = regionOptions as any[]
  const codes: string[] = []
  names.forEach((name) => {
    const n = nodes?.find((x: any) => (x.label || x.name) === name)
    if (n) {
      codes.push(n.value || n.code)
      nodes = n.children || []
    }
  })
  return codes
}

function onRegionFilterChange(codes: string[]) {
  filters.regionCodes = codes || []
  filters.location_admin = labelsFromCodes(codes || [])
}

async function loadActivityTypes() {
  const { data } = await api.get('/dictionaries/items', { params: { type_code: 'activity_type', page_size: 200 } })
  activityTypes.value = data
  const c2i: Record<string, string> = {}
  const i2c: Record<string, string> = {}
  const i2n: Record<string, string> = {}
  data.forEach((d: DictItem) => { c2i[d.code] = d.id; i2c[d.id] = d.code; i2n[d.id] = d.name })
  codeToId.value = c2i
  idToCode.value = i2c
  idToName.value = i2n
}

function reload() {
  page.value = 1
  load()
}

function onPageChange(p: number) {
  page.value = p
  load()
}

function onSizeChange(s: number) {
  pageSize.value = s
  page.value = 1
  load()
}

const showDialog = ref(false)
const dialogTitle = ref('新建活动')
const saving = ref(false)
const editingId = ref<string | null>(null)
const formRef = ref()

const form = reactive<Activity>({
  id: '',
  name: '',
  activity_type_id: '',
  time_start: null,
  time_end: null,
  location_admin: '',
  location_detail: '',
  latitude: null,
  longitude: null,
  description: '',
  organizer: '',
  contact_name: '',
  contact_phone: '',
  approver_name: '',
  approved_at: null,
  approval_result: '',
  status: 'draft',
})

const formRegionCodes = ref<string[]>([])
function onRegionFormChange(codes: string[]) {
  formRegionCodes.value = codes || []
  form.location_admin = labelsFromCodes(codes || [])
}

const rules = {
  name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
  activity_type_id: [{ required: true, message: '请选择活动类型', trigger: 'change' }],
  location_admin: [{ required: true, message: '请选择行政区划', trigger: 'change' }],
  location_detail: [],
  description: [{ required: true, message: '请输入描述', trigger: 'blur' }],
  time_start: [{ required: true, message: '请选择开始日期', trigger: 'change' }],
  time_end: [{ required: true, message: '请选择结束日期', trigger: 'change' }],
  status: [{ required: true, message: '请选择状态', trigger: 'change' }],
}

function openCreate() {
  dialogTitle.value = '新建活动'
  editingId.value = null
  Object.assign(form, {
    id: '',
    name: '',
    activity_type_id: '',
    time_start: null,
    time_end: null,
    location_admin: '',
    location_detail: '',
    latitude: null,
    longitude: null,
    description: '',
    organizer: '',
    contact_name: '',
    contact_phone: '',
    approver_name: '',
    approved_at: null,
    approval_result: '',
    status: 'draft',
  })
  formRegionCodes.value = []
  showDialog.value = true
}

function openEdit(row: Activity) {
  dialogTitle.value = '修改活动'
  editingId.value = row.id
  Object.assign(form, row)
  form.activity_type_id = idToCode.value[row.activity_type_id] || ''
  formRegionCodes.value = codesFromLabels(row.location_admin || '')
  showDialog.value = true
}

async function submit() {
  if (formRef.value) {
    const ok = await new Promise<boolean>((resolve) => formRef.value.validate((v: boolean) => resolve(v)))
    if (!ok) return
  }
  saving.value = true
  const payload: any = { ...form }
  if (payload.activity_type_id) {
    const code = payload.activity_type_id
    payload.activity_type_id = codeToId.value[code] || code
  }
  if (!payload.time_start) delete payload.time_start
  if (!payload.time_end) delete payload.time_end
  try {
    if (editingId.value) {
      await api.put(`/activities/${editingId.value}`, payload)
    } else {
      await api.post('/activities', payload)
    }
    showDialog.value = false
    await load()
  } finally {
    saving.value = false
  }
}

async function remove(row: Activity) {
  await api.delete(`/activities/${row.id}`)
  await load()
}

onMounted(async () => {
  await Promise.all([loadActivityTypes(), load()])
})

// Map picker
const showMap = ref(false)
const mapEl = ref<HTMLDivElement | null>(null)
let map: L.Map | null = null
let mark: L.CircleMarker | null = null
const mapSearchText = ref('')
const geoLoading = ref(false)

function openMapPicker() {
  showMap.value = true
  nextTick(initMap)
}

function initMap() {
  if (!mapEl.value) return
  const center: [number, number] = [form.latitude || 30.6, form.longitude || 114.3]
  if (!map) {
    map = L.map(mapEl.value).setView(center, 11)
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap' }).addTo(map)
    map.on('click', (e: any) => {
      const { lat, lng } = e.latlng
      form.latitude = lat
      form.longitude = lng
      if (mark) mark.remove()
      mark = L.circleMarker([lat, lng], { radius: 8, color: '#2c7', fillColor: '#2c7', fillOpacity: 0.9 }).addTo(map!)
    })
  } else {
    map.setView(center, 11)
    map.invalidateSize()
  }
}

function confirmMapPick() {
  showMap.value = false
  const t = mapSearchText.value.trim()
  if (t) form.location_detail = t
}

function onMapOpened() {
  initMap()
  if (map) map.invalidateSize()
  // 预填搜索文本并尝试根据地址定位
  const composed = [form.location_admin || '', form.location_detail || ''].filter(Boolean).join(' ')
  if (composed && !form.latitude && !form.longitude) {
    mapSearchText.value = composed
    onMapSearch()
  } else if (composed) {
    mapSearchText.value = composed
  }
}

function onMapClosed() {
  if (mark) { try { mark.remove() } catch {} ; mark = null }
  if (map) { try { map.remove() } catch {} ; map = null }
}

async function onMapSearch() {
  const q = mapSearchText.value.trim()
  if (!q) return
  geoLoading.value = true
  try {
    const url = `https://nominatim.openstreetmap.org/search?format=json&limit=1&q=${encodeURIComponent(q)}`
    const resp = await fetch(url, { headers: { 'Accept': 'application/json' } })
    const data = await resp.json()
    if (Array.isArray(data) && data.length) {
      const { lat, lon } = data[0]
      const latNum = Number(lat), lonNum = Number(lon)
      form.latitude = latNum
      form.longitude = lonNum
      if (map) {
        map.setView([latNum, lonNum], 14)
        if (mark) mark.remove()
        mark = L.circleMarker([latNum, lonNum], { radius: 8, color: '#2c7', fillColor: '#2c7', fillOpacity: 0.9 }).addTo(map)
      }
    }
  } catch {}
  finally { geoLoading.value = false }
}
</script>

<style scoped>
/* 页面根容器：确保占满整个父容器高度 */
.page { 
  height: 100%; 
  display: flex; 
  flex-direction: column; 
  box-sizing: border-box;
  overflow: hidden;
}

/* 工具栏：固定高度，不伸缩 */
.toolbar { 
  flex-shrink: 0; 
  display: flex; 
  align-items: center; 
  justify-content: space-between; 
  gap: 12px; 
  padding-bottom: 16px; 
  box-sizing: border-box;
}

.filters { flex: 1; }
.actions { flex-shrink: 0; }

/* 表格区域：占据剩余所有空间 */
.table-area { 
  flex: 1; 
  display: flex; 
  flex-direction: column; 
  min-height: 0;
  overflow: hidden;
}

/* 表格容器：精确控制高度，确保分页固定在底部 */
.table-container {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: relative;
}

/* Element Plus表格深度样式覆盖 */
.table-container :deep(.el-table) {
  height: 100% !important;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.table-container :deep(.el-table__inner-wrapper) {
  height: 100% !important;
  display: flex;
  flex-direction: column;
  flex: 1;
}

/* 表格头部：固定高度 */
.table-container :deep(.el-table__header-wrapper) {
  flex-shrink: 0;
  height: auto !important;
}

/* 表格主体：占据剩余空间，内部滚动 */
.table-container :deep(.el-table__body-wrapper) {
  flex: 1;
  overflow-y: auto !important;
  height: auto !important;
  min-height: 200px; /* 确保最少显示几行数据 */
}

/* 空数据状态 */
.table-container :deep(.el-table__empty-block) {
  min-height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 分页：固定在底部 */
.pagination { 
  flex-shrink: 0; 
  display: flex; 
  justify-content: flex-end; 
  padding-top: 16px; 
  padding-bottom: 8px;
  box-sizing: border-box;
  background: white;
  border-top: 1px solid #f0f0f0;
  margin-top: auto; /* 确保固定在底部 */
}

.map-picker { height: 480px; width: 100%; }
.map-tools { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }

/* 响应式优化 */
@media (max-width: 768px) {
  .toolbar {
    flex-direction: column;
    align-items: stretch;
  }
  
  .filters {
    margin-bottom: 12px;
  }
  
  .pagination {
    justify-content: center;
  }
}
</style>
